package cn.lili.modules.search.serviceimpl;

import cn.lili.modules.lucene.LuceneUtil;
import cn.lili.modules.lucene.SafeIndexAccessService;
import cn.lili.modules.lucene.SearcherManagerProvider;
import cn.lili.modules.search.entity.dos.EsGoodsIndex;
import org.apache.lucene.document.Document;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.TermQuery;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.store.LockObtainFailedException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.List;
import java.util.function.Function;

/**
 * @Author Sylow
 * @Description
 * @Date: Created in 16:56 2025/6/20
 */
@Service
public class GoodsIndexService {

    @Autowired
    private SafeIndexAccessService safeIndexAccessService;

    @Autowired
    private SearcherManagerProvider searcherManagerProvider;

    // 添加或更新商品索引
    public void addOrUpdateGoodsIndex(EsGoodsIndex goods) throws LockObtainFailedException {

        safeIndexAccessService.executeWithWriter(writer -> {
            // 使用updateDocument方法可以实现添加或更新
            Document doc = LuceneUtil.convertToDocument(goods);
            Term term = new Term("id", goods.getId());
            try {
                writer.updateDocument(term, doc);
                writer.commit();

                searcherManagerProvider.refresh();
            } catch (IOException e) {
                throw new RuntimeException("更新商品索引失败", e);
            }

            return null;
        });

    }

    // 批量添加或更新
    public void batchAddOrUpdate(List<EsGoodsIndex> goodsList) throws LockObtainFailedException {
        safeIndexAccessService.executeWithWriter(writer -> {
            try {
                for (EsGoodsIndex goods : goodsList) {
                    Document doc = LuceneUtil.convertToDocument(goods);
                    Term term = new Term("id", goods.getId());
                    writer.updateDocument(term, doc);
                }
                writer.commit();

                searcherManagerProvider.refresh();
            } catch (IOException e) {
                throw new RuntimeException("批量更新商品索引失败", e);
            }
            return null;
        });
    }

    // 删除商品索引
    public void deleteGoodsIndex(String id) throws LockObtainFailedException {
        safeIndexAccessService.executeWithWriter(writer -> {
            try {
                writer.deleteDocuments(new Term("id", id));
                writer.commit();

                searcherManagerProvider.refresh();
            } catch (IOException e) {
                throw new RuntimeException("删除商品索引失败", e);
            }
            return null;
        });
    }

    // 批量删除
    public void batchDelete(List<String> ids) throws LockObtainFailedException {
        safeIndexAccessService.executeWithWriter(writer -> {
            try {
                for (String id : ids) {
                    writer.deleteDocuments(new Term("id", id));
                }
                writer.commit();

                searcherManagerProvider.refresh();
            } catch (IOException e) {
                throw new RuntimeException("批量删除商品索引失败", e);
            }
            return null;
        });
    }

    // 根据ID获取商品
    public EsGoodsIndex getGoodsById(String id) {
        Function<IndexSearcher, EsGoodsIndex> searchOperation = searcher -> {
            try {

                Query query = new TermQuery(new Term("id", id));
                TopDocs topDocs = searcher.search(query, 1);
                if (topDocs.scoreDocs.length > 0) {
                    Document doc = searcher.doc(topDocs.scoreDocs[0].doc);
                    return LuceneUtil.convertDocumentToEsGoodsIndex(doc);
                }
                return null;

            } catch (IOException e) {
                throw new RuntimeException("查询商品失败", e);
            }

        };
        return safeIndexAccessService.executeWithSearcher(searchOperation);
    }
}
